'''
Created on January 11, 2010

This module contains all functions and classes related to users and groups
configuration.
'''

import subprocess
from os import popen

class UserAdmin(object) :
    '''handle user administration tasks like add users , delete users , disable users etc..'''
    
    def __init__(self) :
        pass
    
    
    def listAllUsers(self):
        """
        Return a list of all the users on the system.
        """
        usersFile = popen("cat /etc/passwd |cut -d: -f1")
        users = usersFile.read()
        usersFile.close()
        
        users = users.strip().split("\n")
        return users
    

    def listAllGroups(self):
        """
        Return a list of all the groups on the system.
        """
        groupsFile = popen("cat /etc/group |cut -d: -f1")
        groups = groupsFile.read()
        groupsFile.close()
        
        groups = groups.strip().split("\n")
        return groups
    
    
    def addUser (self, userName, password, defaultGroup = None) :
        """
        Add a new user to the system, Works fine on CentOS and Ubuntu.
        """
        
        defaultGroupCommad = ""
        
        # add "-g" to the command string if the user specified the default group. 
        if defaultGroup is not None :
            defaultGroupCommad = " -g " + defaultGroup
        
        # Try to add the user in the Ubuntu syntax.
        returnValue =  subprocess.call("useradd -m " + defaultGroupCommad\
                                       + " " + userName + " -p `mkpasswd "\
                                       + password + " -m sha-512 2> /dev/null` > /dev/null 2>&1",\
                                       shell = True)
        # return True if successful.
        if returnValue == 0 :
            return True
        
        # If it's a syntax error, retry to add the user in the CentOS or RedHat syntax.
        elif returnValue == 2 :
            
            if subprocess.call("useradd -m " + defaultGroupCommad + " " + userName \
                                + " > /dev/null 2>&1", shell = True) :
                return False
            
            else :
                
                # if the user is added successfully, change the password.
                if subprocess.call("echo " + password + " | passwd --stdin " \
                                    + userName + " > /dev/null 2>&1", shell = True):
                    
                    # If failed to change the password, delete the user and return False.
                    subprocess.call("userdel -r " + userName + " > /dev/null 2>&1", shell = True)
                    return False
                
                else:
                    # If succeeded to add the user and change the password, return True.
                    return True
        
        # If the return error isn't a syntax error, return False
        else :
            return False

    
    def delUser (self, userName, delHome = False) :
        """
        delete user account from the system, DOESN't delete the home directory
        by default.
        """
        
        delHomeCommand = ""
        
        # add the option "-r" to the command string if we want to remove the user's home directory.
        if delHome is True :
            delHomeCommand = "-r "
        
        # call the "userdel" command with required options
        if subprocess.call("userdel " + delHomeCommand + userName + " > /dev/null 2>&1", shell = True) :
            return False
        
        # if succeeded, return true.
        else :
            return True
            
    
    def lockUser (self, userName, action) :
        """
        lockUser (userName, action)
        Lock or Unlock A user on the system. Action is either "lock" or "unlock".
        """
        
        # add "-L" to the command string, if the required action is to lock the user.
        if action == "lock" :
            action  = "-L "
        
        # add "-U" to the command string, if the required action is to unlock the user.    
        elif action == "unlock" :
            action = "-U "
        
        # raise the ValueError otherwise.
        else :
            raise ValueError, 'Either "lock" or "unlock" keywords are allowed as action.'
        
        # call the "usermod" command with the specified options.
        if subprocess.call("usermod " + action + userName + " > /dev/null 2>&1", shell = True) :
            return False
        
        # return True if succeeded.
        else :
            return True
    
        
    def changeUserPasswd(self, name, password):
        """
        change user password
        """
        
        if subprocess.call("echo '" + name + ":" + password + "' | chpasswd > /dev/null 2>&1", shell=True):
            return False
        
        else:
            return True
            
    
def main():
    # THE FOLLOWING CODE IS JUST FOR TESTING
    # CODER DISCRITION IS ADVISED :D
    
    x = UserAdmin()
    
    if x.addUser("test3", "test3pass") :
        print "Succeeded to add the user"
    
    else :
        print "Failed to add the user"
    
    print x.listAllUsers()
    
    if x.changeUserPasswd("test3", "someotherpass") :
        print "User's password changed successfully"
    
    else :
        print "failed to change the user's password"
        
    if x.lockUser("test3", "lock"):
        print "user is locked"
    
    else :
        print "error locking the user"
        
    if x.delUser("test3", True) :
        print "Successfully deleted the user"
    
    else :
        print "failed to delete the user"
    
    print x.listAllUsers()
    

if __name__ == "__main__" :
    # Call the main function here to test this module
    # main()
    pass